<template>
    <el-form :model="form" class="form" v-bind="options" :rules="rules||formRules" :ref="options.ref||'ruleForm'" @submit.native.prevent>
        <!-- 遍历formItem -->
        <template v-for="(item,i) in  items">
            <!-- 处理按钮 -->
            <el-form-item v-if="item.type==='button'" :key="i" v-bind="item.formItem">
                <template v-for="(temp,j) in item.formItem.children">
                    <ChfButton :key="j" v-bind="{...temp,loading}" v-if="temp.submit" @click="submitForm(temp)">{{temp.content}}</ChfButton>
                    <el-button :key="j" v-bind="temp" v-else-if="temp.reset" @click="resetClick(temp)">{{temp.content}}</el-button>
                    <el-button :key="j" v-bind="temp" v-else-if="temp.submit===undefined&&item.reset===undefined" v-on="temp">{{temp.content}}</el-button>
                </template>
            </el-form-item>

            <el-form-item v-bind="getFormItemBind(item)" :key="i" :prop="getProp(item)" :class="[item.formItem.children?'children':'']"
                v-else-if="item.formItem">

                <!-- 如果有children   嵌套渲染 -->
                <template v-if="item.formItem.children&&item.formItem.children[0]">
                    <!-- 循环children -->
                    <el-form-item v-for="(formChildrenItem,j) in item.formItem.children" :key="j+'aa'+i" v-bind="formChildrenItem.formItem"
                        :prop="getProp(formChildrenItem)">
                        <!-- 渲染组件 -->
                        <elItem :item="formChildrenItem" :form="form" :ref="formChildrenItem.itemRender.ref||''" />
                    </el-form-item>
                </template>

                <!-- 正常渲染 -->
                <template v-else>
                    <elItem :item="item" :form="form" :ref="item.itemRender.ref||''" />
                </template>
            </el-form-item>
            <template v-else>
                <slot :name="item.slotName" :formItem="item" :form="form"></slot>
            </template>
        </template>
    </el-form>
</template>

<script>
import elItem from "./elItem.vue";
export default {
    model: {
        prop: "formData",
        event: "formDataChange",
    },
    props: {
        //el-form 相关配置
        options: {
            type: Object,
            default: () => {
                return {};
            },
        },
        //el-form-item 配置
        items: {
            type: Array,
            default: () => [],
        },
        //校验配置
        rules: {
            type: Object,
            default: null,
        },
        //按钮配置
        btns: {
            type: Array,
            default: () => [],
        },
        //form 默认值配置 或者回显
        formData: {
            type: Object,
            default: () => {
                return {};
            },
        },
        formDataChange: {
            type: Function,
            default: null,
        },
    },
    data () {
        return {
            // 表单绑定对象
            form: {},
            //表单校验
            formRules: {},
            // 重置表单
            resetForm: {},
            // 默认有提交和重置按钮  setBtn（） 传了就位false
            // isSubmit: true,
            // isReset: false,
            uploadRefList: [],
            loading: false,
        };
    },
    created () {
        // 初始化
        this.init();
    },
    methods: {
        init () {
            // 获取form
            this.getFormAndRules(this.items);

            //回显
            if (this.formData) {
                this.setForm();
            }

            //监听form
            this.formDataChange &&
                this.$watch("form", (a, b) => {
                    this.formDataChange(a, b);
                },
                    { deep: true }
                );
        },
        // 通过this.items获取form 和 rules
        getFormAndRules (list) {
            let form = {};
            list.forEach((item, i) => {
                if (item.type === 'button') {
                    return
                }
                // 嵌套form处理
                if (item.formItem?.children?.[0]) {
                    item.formItem.children.forEach((temp, j) => {
                        if (temp.itemRender?.value) {
                            //添加form
                            form[temp.itemRender.value] = this.setFormDefVal(temp.itemRender);
                            // 添加校验规则
                            if (item.formItem.required === true && temp.formItem?.required !== false) {
                                this.formRules[temp.itemRender.value] = this.getRules(temp);
                            }

                            //如果里面有上传组件 添加和记录ref
                            if (temp.itemRender?.el === "ChfUpload") {
                                temp.itemRender.ref = "ChfUpload" + i + j;
                                this.uploadRefList.push("ChfUpload" + i + j);
                            }
                            temp.itemRender.query?.(temp.itemRender);
                        }
                    });
                    // 一层处理
                } else if (item.itemRender?.value) {
                    //添加form
                    form[item.itemRender.value] = this.setFormDefVal(item.itemRender);
                    // 添加校验规则
                    if (item.formItem?.required === true || item.formItem?.validator) {
                        this.formRules[item.itemRender.value] = this.getRules(item);
                    }

                    //如果里面有上传组件 添加和记录ref
                    if (item.itemRender?.el === "ChfUpload") {
                        item.itemRender.ref = "ChfUpload" + i;
                        this.uploadRefList.push("ChfUpload" + i);
                    }
                    item.itemRender.query?.(item.itemRender);
                    //处理插槽
                } else if (item.slotName) {
                    Object.keys(item.value).forEach((temp) => {
                        form[temp] = item.value[temp];
                    });
                }
            });
            this.resetForm = JSON.parse(JSON.stringify(form));
            this.form = form;
            console.log(this.form);
        },
        //设置form值
        setForm () {
            Object.keys(this.formData).forEach((item) => {
                this.form[item] = this.formData[item];
            });
            this.$emit('formDataChange', this.form)
        },
        // 提交
        submitForm (item) {
            return new Promise((resolve, reject) => {
                this.$refs[this.options.ref ?? "ruleForm"].validate(
                    async (valid) => {
                        if (valid) {
                            this.loading = true;
                            this.uploadRefList[0] && await this.submitUpload()
                            let form = { ...this.form };
                            this.$emit("submit", form);
                            item?.click?.(form);
                            resolve(form);
                            this.loading = false;
                        }
                    }
                );
            });
        },
        //上传文件
        async submitUpload () {
            try {
                await Promise.all(
                    this.uploadRefList.map((item) => {
                        return this.$refs[item][0].$refs[item].submitUpload();
                    })
                );
                return Promise.resolve(true);
            } catch (error) {
                this.$message.error("文件上传失败");
                this.loading = false;
                return Promise.reject(error);
            }
        },
        //重置事件
        resetClick (item) {
            this.form = JSON.parse(JSON.stringify(this.resetForm));
            // this.form = { ...this.resetForm };
            this.$refs[this.options.ref ?? "ruleForm"].resetFields();
            item.click?.(this.form);
        },
        // 设置form绑定valeu的默认值
        setFormDefVal (itemRender) {
            if (itemRender.defVal) {
                return itemRender.defVal;
            } else {
                switch (itemRender.el) {
                    case "el-checkbox-group":
                    case "ChfUpload":
                    case "ChfSesectTree":
                        return [];
                    case "ChfTinymce":
                        return "";
                    default:
                        return null;
                }
            }
        },
        // 获取绑定的prop
        getProp (item) {
            return item.formItem?.prop ?? item.itemRender?.value ?? "";
        },
        //获取校验规则
        getRules (item) {
            switch (item.itemRender.el) {
                case "el-input":
                case "ChfTinymce":
                    if (item.formItem?.validator) {
                        return {
                            trigger: "blur",
                            validator: item.formItem.validator,
                        };
                    } else {
                        return {
                            required: true,
                            message: `请输入${item.itemRender.placeholder || item.formItem.label}`,
                            trigger: "blur",
                        };
                    }

                case "el-select":
                case "el-cascader":
                case "el-date-picker":
                case "el-time-picker":
                case "el-checkbox-group":
                case "el-radio-group":
                case "ChfSesectTree":
                    if (item.formItem?.validator) {
                        return {
                            trigger: "change",
                            validator: item.formItem.validator,
                        };
                    } else {
                        return {
                            required: true,
                            message: `请选择${item.itemRender.placeholder || item.formItem.label}`,
                            trigger: "change",
                            validator: item.formItem?.validator,
                        };
                    }
                case "ChfUpload":
                    return {
                        required: true,
                        message: `请上传${item.itemRender.placeholder || "文件"}`,
                        trigger: "change",
                        validator: item.formItem?.validator,
                    };
            }
        },
        //获取form-item bind
        getFormItemBind (item) {
            let options = { ...item.formItem };
            !item.formItem?.children && !item.formItem.validator && this.$delete(options, "required");
            return options;
        },
    },
    components: {
        elItem,
    },
};
</script>

<style lang="scss" scoped>
.form {
    .children {
        // margin-bottom: 0;
        ::v-deep .el-form-item__content {
            display: flex;
        }
        ::v-deep .el-form-item {
            margin-right: 15px;
        }
        ::v-deep .el-form-item--mini.el-form-item,
        .el-form-item--small.el-form-item {
            margin-bottom: 0;
        }
    }
}
</style>